#!/usr/bin/python3
# -*- coding: utf-8 -*-
#======================================#
# @Author   : duanqizhong
# @time     : 2022-8-16 10:54
# @file     : cls
# @Software : PyCharm
#======================================#
import json
import os
from configparser import ConfigParser

import paramiko
import pymysql
from base.logger import log
import requests
from settings import CONNECT_TIMEOUT


class ParseConf:
    """解析conf"""

    def __init__(self, path, encoding="utf-8"):
        if not os.path.exists(path):
            raise Exception(f"path={path} not found!")
        self.path = path
        self.parse = ConfigParser()
        self.parse.read(path, encoding=encoding)
        # self.parse.read(path)

    def get_section_options(self, section):
        """获取配置文件内section的options"""
        return self.parse.options(section)

    def get_sections(self):
        """获取配置文件内sections"""
        return self.parse.sections()

    def check_section(self, section):
        """检查指定的section是否存在"""
        if section in self.get_sections():
            return True
        else:
            return None

    def check_option(self, section, option):
        """检查是否存在option"""
        if not self.check_section(section):
            return False
        if option in self.get_section_options(section):
            return True
        else:
            return False

    def get_section_info(self, section):
        """
        获取section的key=value
        default section的值会被获取到，被作为默认值
        如果指定的section不存在，返回{}；否则返回key,value
        """
        section_info = {}
        if self.check_section('default'):
            default_options = self.get_section_options('default')
            for option in default_options:
                section_info[option] = self.parse.get('default', option)
        if section == 'default':
            return section_info
        if self.check_section(section):
            section_options = self.get_section_options(section)
            for option in section_options:
                section_info[option] = self.parse.get(section, option)
        else:
            return {}
        return section_info

    def get_sections_info(self):
        """获取所有sections info，section:{key=value}"""
        sections = self.get_sections()
        sections_info = {}
        for section in sections:
            sections_info[section] = self.get_section_info(section)
        return sections_info

    def set_section_info(self, section):
        if not self.check_section(section):
            self.parse.add_section(section)
            return True
        return False

    def add_section_info(self, section, key, value):
        if not self.check_section(section):
            self.set_section_info(section)
        self.parse.set(section, key, value)
        return True

    def writeback(self, encoding='utf-8'):
        self.parse.write(open(self.path, 'w', encoding=encoding))

class Mysql:
    def __init__(self, conn):
        self.conn = conn
        self.db = None

    def connect(self, database):
        """连接数据库"""
        self.db = pymysql.connect(host=self.conn["host"],
                                  port=self.conn["port"],
                                  user=self.conn["username"],
                                  passwd=self.conn["password"],
                                  database=database,
                                  use_unicode=True,
                                  charset='utf8')
        return self

    def commit(self):
        if self.db is not None:
            self.db.commit()

    def close(self):
        if self.db is not None:
            self.db.close()
            self.db = None

    def execute(self, sql):
        cursor = self.db.cursor()
        try:
            cursor.execute(sql)
            cursor.close()
        except Exception as e:
            self.db.rollback()
            log.error(f"{self.conn}# {e}")
            return False

        return True

    def fetchone(self, sql, key_lower=False):
        cursor = self.db.cursor()
        cursor.execute(sql)
        if key_lower:
            columns = [col[0].lower() for col in cursor.description]
        else:
            columns = [col[0] for col in cursor.description]
        record = cursor.fetchone()
        cursor.close()
        if record:
            return dict(zip(columns, record))
        return None

    def fetchall(self, sql, key_lower=False):
        cursor = self.db.cursor()
        cursor.execute(sql)
        if key_lower:
            columns = [col[0].lower() for col in cursor.description]
        else:
            columns = [col[0] for col in cursor.description]
        all_result = [dict(zip(columns, row)) for row in cursor.fetchall()]
        cursor.close()
        return all_result

    def query_time(self,sql):
        spend_time=0
        cursor = self.db.cursor()


class Ding:
    def __init__(self, token):
        self.url = f"https://oapi.dingtalk.com/robot/send?access_token={token}"
        self.headers = {"content-Type": "application/json;charset=UTF-8"}

    def send_text(self, text):
        textMsg = {
            "msgtype": "text",
            "text": {"content": text}
        }
        try:
            requests.post(self.url, json=textMsg, headers=self.headers, timeout=CONNECT_TIMEOUT)
        except Exception as e:
            log.error(f"send_dingding发送失败：{e}")
            pass

    def send_link(self, title, text, link, token):
        # token='f380f3b2791bec3dc584544703432aa3b4ce81af8b9bf82df936ca5ee10bf6ef'
        testMsg = {
            "msgtype": "link",
            "link": {
                "text": text,
                "title": title,
                "picUrl": "",
                "messageUrl": link
            }
        }
        try:
            send_msg = json.dumps(testMsg).encode("utf-8")
            requests.post(url=self.url, data=send_msg, headers=self.headers, timeout=5)
        except Exception as e:
            log.error(f"send_dingding_link发送失败：{e}")
            pass


class FeiShu:
    def __init__(self, token):
        self.url = f"https://open.feishu.cn/open-apis/bot/hook/{token}"
        self.headers = {"content-Type": "application/json;charset=UTF-8"}

    def send_text(self, title, text):
        textMsg = {
            "title": title,
            "text": text
        }
        try:
            requests.post(self.url, json=textMsg, headers=self.headers, timeout=CONNECT_TIMEOUT)
        except Exception as e:
            log.error(f"send_feishu发送失败：{e}")
            pass


class QYWX:
    def __init__(self, token):
        self.url = f"https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key={token}"
        self.headers = {"content-Type": "application/json;charset=UTF-8"}
        self.timeout = 3

    def send_text(self, title, text):
        textMsg = {
            "msgtype": "text",
            "text": {"content": f"{title}:{text}"}
        }
        try:
            requests.post(self.url, json=textMsg, headers=self.headers, timeout=self.timeout)
        except Exception as e:
            log.error(f"send_qiyewx发送失败：{e}")
            return False
        return True


class SSHClient:
    def __init__(self, host, key_path, username='root', port=22):
        self.host = host
        self.port = port
        self.key_path = key_path
        self.username = username

    def ssh_cmd(self, command, username='root'):
        pkey = paramiko.RSAKey.from_private_key_file(self.key_path)
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        # sin=None
        sout = None
        serr = None
        try:
            ssh.connect(hostname=self.host, port=self.port, username=self.username, pkey=pkey)
            log.info("正在host={host} 上执行 {command}".format(host=self.host, command=command))
            stdin, stdout, stderr = ssh.exec_command(command)
            # sin=stdin.read()
            sout = stdout.read()
            serr = stderr.read()
        except Exception as e:
            log.error(str(e))
        finally:
            try:
                ssh.close()
            except Exception as e:
                log.error(str(e))
        return sout, serr